package com.simon.seckill.intercept;

import com.simon.seckill.Entities.IPRequestRecords;
import com.simon.seckill.cache.IPBlackListCache;
import com.simon.seckill.conf.SystemConf;
import com.simon.seckill.constant.CommonConstant;
import com.simon.seckill.constant.RegularPattern;
import com.simon.seckill.mq.handler.SeckillRequestHandler;
import com.simon.seckill.unit.IPUtil;
import com.simon.seckill.unit.RedisUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.MessageFormat;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SystemConf systemConf;

    @Autowired
    private IPBlackListCache ipBlackListCache;

    private Pattern pattern = Pattern.compile(RegularPattern.IP_PATTERN);

    private static Log logger = LogFactory.getLog(SeckillRequestHandler.class);


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 获取真实的IP
        String ip = IPUtil.getIp(request);

        logger.info(ip+"进入");

        Matcher matcher = pattern.matcher(ip);
        if (!matcher.find() || ipBlackListCache.isIn(ip)) {
            logger.info(ip+"已经被拉黑了");
            return false;
        }

        // 获取该ip的访问次数
        List<IPRequestRecords> ipRequestRecords = redisUtil.lrange(getKey(ip),0, systemConf.getIpBlackTimes()-1, IPRequestRecords.class);

        if (ipRequestRecords.size()+1>systemConf.getIpBlackTimes() &&
                (System.currentTimeMillis()-ipRequestRecords.get(ipRequestRecords.size()-1).getTimestamp()) <
                        systemConf.getIpBlackSeconds()*1000) {
            logger.info(ip+"正在被拉黑了");

            redisUtil.delete(getKey(ip));

            ipBlackListCache.add(ip);
            return true;
        } else {
            IPRequestRecords records = new IPRequestRecords();
            records.setIp(ip);
            records.setTimestamp(System.currentTimeMillis());
            redisUtil.lpush(getKey(ip), records);
        }

        return true;
    }

    private String getKey(String ip) {
        return MessageFormat.format(CommonConstant.RedisKey.IP_REQUEST_TIMES, new Object[]{ip});
    }
}